Explicitly update widget a11y bounds when allocating
authorEmmanuele Bassi <ebassi@gnome.org>
Mon, 20 Apr 2020 16:10:40 +0000 (17:10 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 6 May 2020 18:27:45 +0000 (14:27 -0400)
The a11y machinery is using signal subscription to get notified of size
changes and notify listeners in turn. This is suboptimal for a couple of
reasons:

 - if something connects to the GtkWidget::size-allocate signal we need
   to emit it; currently, we have an optimization in place that will
   skip the signal emission if there are no handlers, and it would be
   nice to go through the fast path
 - the accessibility implementation is part of GTK, and should not go
   through additional hoops like any out-of-tree API consumer

gtk/a11y/gtkwidgetaccessible.c
gtk/a11y/gtkwidgetaccessibleprivate.h
gtk/gtkwidget.c

index 84732dcda59c10793053a39e79a89cdac04ef563..43b9c8cb9ab7d86ecdcd356d64ec8ab12ebd539a 100644 (file)
@@ -54,28 +54,28 @@ notify_cb (GObject    *obj,
     klass->notify_gtk (obj, pspec);
 }
 
-/* Translate GtkWidget::size-allocate to AtkComponent::bounds-changed */
-static void
-size_allocate_cb (GtkWidget *widget,
-                  int        width,
-                  int        height)
+/*< private >
+ * gtk_widget_accessible_update_bounds:
+ * @self: a #GtkWidgetAccessible
+ *
+ * Updates the bounds of the widget's accessible implementation using
+ * the widget's allocation.
+ */
+void
+gtk_widget_accessible_update_bounds (GtkWidgetAccessible *self)
 {
-  AtkObject* accessible;
+  GtkAllocation alloc;
   AtkRectangle rect;
 
-  accessible = gtk_widget_get_accessible (widget);
-  if (ATK_IS_COMPONENT (accessible))
-    {
-      GtkAllocation alloc;
-      gtk_widget_get_allocation (widget, &alloc);
+  GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (self));
+  gtk_widget_get_allocation (widget, &alloc);
 
-      rect.x = alloc.x;
-      rect.y = alloc.y;
-      rect.width = alloc.width;
-      rect.height = alloc.height;
+  rect.x = alloc.x;
+  rect.y = alloc.y;
+  rect.width = alloc.width;
+  rect.height = alloc.height;
 
-      g_signal_emit_by_name (accessible, "bounds-changed", &rect);
-    }
+  g_signal_emit_by_name (self, "bounds-changed", &rect);
 }
 
 /* Translate GtkWidget mapped state into AtkObject showing */
@@ -109,7 +109,6 @@ gtk_widget_accessible_initialize (AtkObject *obj,
   widget = GTK_WIDGET (data);
 
   g_signal_connect (widget, "notify", G_CALLBACK (notify_cb), NULL);
-  g_signal_connect (widget, "size-allocate", G_CALLBACK (size_allocate_cb), NULL);
   g_signal_connect (widget, "map", G_CALLBACK (map_cb), NULL);
   g_signal_connect (widget, "unmap", G_CALLBACK (map_cb), NULL);
 
index 96234295010904d06fbc78ca25269ad17c69e5cc..ac60f0e43d5f0a8a9a7774104579476299e367f1 100644 (file)
@@ -25,6 +25,8 @@ G_BEGIN_DECLS
 void _gtk_widget_accessible_set_layer (GtkWidgetAccessible *accessible,
                                        AtkLayer             layer);
 
+void gtk_widget_accessible_update_bounds (GtkWidgetAccessible *self);
+
 G_END_DECLS
 
 #endif /* __GTK_WIDGET_ACCESSIBLE_PRIVATE_H__ */
index f52ef856ce11c047fca91a702b8bb19ebdc4d90f..f873f2b4ffebaab73791b23406c45afaffc61eb2 100644 (file)
@@ -74,7 +74,7 @@
 #include "gtknativeprivate.h"
 #include "gtkconstraint.h"
 
-#include "a11y/gtkwidgetaccessible.h"
+#include "a11y/gtkwidgetaccessibleprivate.h"
 #include "inspector/window.h"
 
 #include "gdk/gdkeventsprivate.h"
@@ -4123,6 +4123,9 @@ gtk_widget_allocate (GtkWidget    *widget,
 
   gtk_widget_update_paintables (widget);
 
+  if (priv->accessible != NULL)
+    gtk_widget_accessible_update_bounds (GTK_WIDGET_ACCESSIBLE (priv->accessible));
+
 skip_allocate:
   if (size_changed || baseline_changed)
     gtk_widget_queue_draw (widget);